package com.ke.searchhouse.controller.house;

import com.ke.searchhouse.base.RentValueBlock;
import com.ke.searchhouse.base.Response;
import com.ke.searchhouse.dto.HouseBucketDTO;
import com.ke.searchhouse.dto.HouseDTO;
import com.ke.searchhouse.dto.SupportAddressDTO;
import com.ke.searchhouse.dto.UserDTO;
import com.ke.searchhouse.entity.SupportAddress;
import com.ke.searchhouse.form.MapSearch;
import com.ke.searchhouse.form.RentSearch;
import com.ke.searchhouse.service.IAddressService;
import com.ke.searchhouse.service.IHouseService;
import com.ke.searchhouse.service.ISearchService;
import com.ke.searchhouse.service.IUserService;
import com.ke.searchhouse.util.ServiceMultiResult;
import com.ke.searchhouse.util.ServiceResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Map;

@RequestMapping("/rent/house")
@Controller
public class HouseController {
    @Autowired
    private IAddressService addressService;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ISearchService searchService;


     @GetMapping("")
     public String rentHousePage(@ModelAttribute RentSearch rentSearch, Model model,
                                 HttpSession session, RedirectAttributes redirectAttributes) {

        if (StringUtils.isBlank(rentSearch.getCityEnName())) {
            String cityEnNameInSession = (String) session.getAttribute("cityEnName");

            if (StringUtils.isBlank(cityEnNameInSession)) {
                redirectAttributes.addAttribute("msg", "must_chose_city");
                return "redirect:/index";
            }

            rentSearch.setCityEnName(cityEnNameInSession);
        } else {
            session.setAttribute("cityEnName", rentSearch.getCityEnName());
        }

        ServiceResult<SupportAddressDTO> cityResult = addressService.findCity(rentSearch.getCityEnName());

        model.addAttribute("currentCity", cityResult.getResult());

        if (!cityResult.isSuccess()) {
            redirectAttributes.addAttribute("msg", "must_chose_city");
            return "redirect:/index";
        }

        ServiceMultiResult<SupportAddressDTO> addressResult =
                addressService.findAllRegionsByCityName(rentSearch.getCityEnName());

        if (addressResult.getResult() == null || addressResult.getTotal() < 1) {
            redirectAttributes.addAttribute("msg", "must_chose_city");
            return "redirect:/index";
        }

        ServiceMultiResult<HouseDTO> serviceMultiResult = houseService.query(rentSearch);

        model.addAttribute("total", serviceMultiResult.getTotal());
        model.addAttribute("houses", serviceMultiResult.getResult());

        if (rentSearch.getRegionEnName() == null) {
            rentSearch.setRegionEnName("*");
        }

        model.addAttribute("searchBody", rentSearch);
        model.addAttribute("regions", addressResult.getResult());

        model.addAttribute("priceBlocks", RentValueBlock.PRICE_BLOCK);
        model.addAttribute("areaBlocks", RentValueBlock.AREA_BLOCK);

        model.addAttribute("currentPriceBlock", RentValueBlock.matchPrice(rentSearch.getPriceBlock()));
        model.addAttribute("currentAreaBlock", RentValueBlock.matchPrice(rentSearch.getAreaBlock()));

        return "rent-list";
     }

    @GetMapping("/show/{id}")
    public String show(@PathVariable(value = "id") Long houseId,
                       Model model) {
        if (houseId <= 0) {
            return "404";
        }

        ServiceResult<HouseDTO> serviceResult = houseService.findCompleteOne(houseId);
        if (!serviceResult.isSuccess()) {
            return "404";
        }

        HouseDTO houseDTO = serviceResult.getResult();
        Map<SupportAddress.Level, SupportAddressDTO>
                addressMap = addressService.findCityAndRegion(houseDTO.getCityEnName(), houseDTO.getRegionEnName());

        SupportAddressDTO city = addressMap.get(SupportAddress.Level.CITY);
        SupportAddressDTO region = addressMap.get(SupportAddress.Level.REGION);

        model.addAttribute("city", city);
        model.addAttribute("region", region);

        ServiceResult<UserDTO> userDTOServiceResult = userService.findById(houseDTO.getAdminId());
        model.addAttribute("agent", userDTOServiceResult.getResult());
        model.addAttribute("house", houseDTO);

        ServiceResult<Long> aggResult = searchService.aggregateDistrictHouse(city.getEnName(),
                region.getEnName(), houseDTO.getDistrict());
        model.addAttribute("houseCountInDistrict",aggResult.getResult());

        return "house-detail";
    }


    @GetMapping("/autocomplete")
    @ResponseBody
    public Response autocomplete(@RequestParam("prefix") String prefix) {
         if (StringUtils.isBlank(prefix)) {
             return Response.ofStatus(Response.Status.BAD_REQUEST);
         }

         ServiceResult result = searchService.suggest(prefix);

         return Response.ofSuccess(result.getResult());
    }


    @GetMapping("/map")
    public String rentMapPage(@RequestParam("cityEnName") String cityEnName, Model model,
                              HttpSession session, RedirectAttributes redirectAttributes) {
         ServiceResult<SupportAddressDTO> city = addressService.findCity(cityEnName);

         if (!city.isSuccess()) {
             redirectAttributes.addAttribute("msg", "must_choose_city");
             return "redirect:/index";
         }

         session.setAttribute("cityName", cityEnName);
         model.addAttribute("city", city.getResult());

         ServiceMultiResult<SupportAddressDTO> region = addressService.findAllRegionsByCityName(cityEnName);
         ServiceMultiResult<HouseBucketDTO> serviceMultiResult = searchService.mapAggregate(cityEnName);

         model.addAttribute("total", serviceMultiResult.getTotal());
         model.addAttribute("aggData", serviceMultiResult.getResult());
         model.addAttribute("regions", region.getResult());

         return "rent-map";
    }


    @RequestMapping("/map/houses")
    @ResponseBody
    public Response rentMapHouses(@ModelAttribute MapSearch mapSearch) {
         if (StringUtils.isBlank(mapSearch.getCityEnName())) {
             return Response.ofMessage(HttpStatus.SC_BAD_REQUEST, "必须选择城市");
         }

        ServiceMultiResult<HouseDTO> result;

         if (mapSearch.getLevel() < 13) {
             result = houseService.wholeMapQuery(mapSearch);
         } else {
             // 地图边界内房源
             result = houseService.boundMapQuery(mapSearch);
         }

         Response response = Response.ofSuccess(result.getResult());
         response.setMore(result.getTotal() > (mapSearch.getStart() + mapSearch.getSize()));

         return response;
    }

}
